<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // Symbol起源

    // 对象的键名都是字符串类型

    // var zhang = { name: "张三", age: 18, height: "177cm", weight: "70kg" };

    // zhang["name"] = "李四";  //对象属性名 重新赋值 => 后面的就会覆盖前面的

    // console.log(zhang);

    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），新方法的名字就有可能与现有方法产生冲突

    // console.log(Math); // Math => 官方定义的全局对象

    // 给官方定义一个方法  => 随机指定范围内的整数

    // 你同桌欠你999  -> 你说:今天至少还我100 (100-999)
    // 解析: 100 + 剩余899 (0 - 899)

    // Math.randomInt = function (min, max) {
    //     // 100-999
    //     // 100 + Math.round(Math.random()*(999-100)))
    //     // 100 + Math.floor(Math.random()*(999-100 + 1))
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // 会覆盖原本的Math.random
    // Math.random = function (min, max) {
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // (1) 老版本解决方法: 在属性名前加前缀_ => 保证不跟以前的方法重名
    // Math._random = function (min, max) {
    //     return min + Math.floor(Math.random()*(max - min + 1));
    // }

    // (2) 如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。


</script>
<script>
    // Symbol  ES6新增数据类型  => 表示独一无二的值

    // ES5 的对象属性名都是字符串，这容易造成属性名的冲突。比如，你使用了一个他人提供的对象，但又想为这个对象添加新的方法（mixin 模式），新方法的名字就有可能与现有方法产生冲突。如果有一种机制，保证每个属性的名字都是独一无二的就好了，这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

    // 传统的数据类型
    // string  number  boolean  null undefined  object(array)

    // ES6新增数据类型
    // symbol  bigInt


    // 如何创建Symbol数据?  => Symbol值通过Symbol()函数生成

    // var s1 = Symbol();
    // console.log(s1);


    // var s2 = Symbol();
    // console.log(s2);

    // console.log(s1 === s2);  // false
    // console.log(typeof s1, typeof s2); // 'symbol'

    // Symbol转字符串
    // console.log(s1.toString());
    // console.log(s2.toString());
    // console.log(s1.toString() == s2.toString());

    // Symbol描述:  可以给Symbol函数传入一个参数(字符串),作为symbol的描述
    // var s1 = Symbol("a");
    // console.log(s1);
    // console.log(s1.description);

    // var s2 = Symbol("b");
    // console.log(s2);
    // console.log(s2.description);


    // Symbol应用:
    // 1. 作为对象的属性名->表示独一无二的值
    //   对象的属性名现在可以有两种类型，一种是原来就有的字符串，另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型，就都是独一无二的，可以保证不会与其他属性名产生冲突。

    var randInt = Symbol("randInt");
    Math[randInt] = function (min, max) {
        return min + Math.floor(Math.random() * (max - min + 1));
    }

    var res = Math[randInt](100, 999);
    console.log(res);


    // 2. 消除魔术字符串









</script>

</html>